package com.gitee.cnlongs.cnlongmq.basic.entitiy.request;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;

import com.gitee.cnlongs.cnlongmq.basic.constant.CnLongMqConstant;
import com.gitee.cnlongs.cnlongmq.basic.enums.CnLongMqMode;
import com.gitee.cnlongs.cnlongmq.basic.enums.CnLongMqRole;
import com.gitee.cnlongs.cnlongmq.basic.enums.CnLongMqStatus;
import com.gitee.cnlongs.cnlongmq.basic.enums.CnLongMqType;

/**
 * 系统名称：CnLongMessageQueue.java
 * 模块名称：
 * 模块描述：中国龙[消息队列] - 队列信息实体类
 * 功能列表：
 * 模块作者：ZOUYONG
 * 开发时间：2019年4月1日 下午8:27:48
 * 模块路径：com.gitee.cnlongs.cnlongmq.basic.entitiy.request.CnLongMessageQueue
 * 更新记录：
 */
public class CnLongMessageQueue extends CnLongMqBaseInfo implements Cloneable {

	// 序列化ID
	private static final long serialVersionUID = 1L;
	
	// 消息ID，加载配置文件时自动生成
	private String id;

	// 消息队列名称，全网唯一
	private String key;

	// 消息的过期时间，单位为秒，0-马上过期，小于0-则不过期
	private Integer timeout = CnLongMqConstant.defaultLongMqTimeOut;

	// 消息类型：点对点/广播（默认是点对点）
	private String type = CnLongMqType.point.name();

	// 消息模式：异步/同步（默认是异步）
	private String mode = CnLongMqMode.async.name();

	// 消息角色：提供者/消费者
	private String role;
	
	// 消息执行对象的类路径
	private String classPath;
	
	// mq服务器的名称，全网唯一，不允许重复
	private String longMqName;
	
	// mq服务器ip
	private String longMqIp;

	// mq服务器端口
	private Integer longMqPort;
	
	// ======================= 队列心跳属性 =======================
	
	// mq队列状态：活动中、已停止 （CnLongMqStatus枚举类）
	private String longMqStatus = CnLongMqStatus.active.name();
	
	// 队列活动开始时间
	private Date startActiveDate;
	
	// 检测心跳的时间
	private Date heartBeatData;
	
	// 队列停止时间
	private Date stopDate;
	
	// 队列心跳尝试连接次数
	private int heartbeatConnectNumber;
	
	public CnLongMessageQueue() {}
	
	public CnLongMessageQueue(String longMqName, String longMqIp, int longMqPort) {
		this.longMqName = longMqName;
		this.longMqIp = longMqIp;
		this.longMqPort = longMqPort;
	}

	/**
	 * 功能描述：校验对象的必填项是否有值
	 * 模块作者：ZOUYONG
	 * 开发时间：2019年4月2日 下午10:26:44
	 * 更新记录：
	 * 返回数据：void
	 */
	public void check() {
		if(	StringUtils.isBlank(this.key) || 
			StringUtils.isBlank(this.type) || 
			StringUtils.isBlank(this.mode) || 
			StringUtils.isBlank(this.role) || 
			StringUtils.isBlank(this.longMqName) || 
			StringUtils.isBlank(this.longMqIp) || 
			null == timeout || null == longMqPort
		) {
			throw new RuntimeException(CnLongMqConstant.longmqDefaultName + "队列配置不能为空！");
		}
	}

	/**
	 * 功能描述：比较两个队列是否一样
	 * 模块作者：ZOUYONG
	 * 开发时间：2019年4月2日 下午10:27:02
	 * 更新记录：
	 * 返回数据：boolean
	 */
	public boolean compareIdentical(CnLongMessageQueue syncSeq) {
		if(this.key.equals(syncSeq.getKey()) && 					// 队列编码一样（编码唯一值）
				this.type.equals(syncSeq.getType()) && 			// 队列类型一样（广播、点对点）
				this.mode.equals(syncSeq.getMode()) && 			// 队列模式一样（同步、异步）
				this.role.equals(syncSeq.getRole()) && 			// 队列角色一样（提供者、还是消费者）
				this.longMqIp.equals(syncSeq.getLongMqIp()) &&	// 队列的ip一样
				this.longMqPort.equals(syncSeq.getLongMqPort())	// 队列的端口一样
		) {
			return true;
		}
		return false;
	}
	
	/**
	 * 功能描述：消息中序列信息与当前序列比较是否是同一个
	 × 模块作者：ZOUYONG
	 × 开发时间：2019年7月26日 下午5:53:24
	 × 返回数据：boolean
	 */
	public boolean compareByMqMessage(CnLongMqMessage mqMessage) {
		if(this.key.equals(mqMessage.getLongMqKey()) && 
				this.role.equals(mqMessage.getLongMqRole()) && 
				this.longMqIp.equals(mqMessage.getCustomerServerIp()) && 
				this.longMqPort.equals(mqMessage.getCustomerPort())
		) {
			return true;
		}
		return false;
	}
	
	/**
	 * 功能描述：判断队列是否可用
	 × 模块作者：ZOUYONG
	 × 开发时间：2019年7月30日 下午1:49:19
	 × 返回数据：boolean
	 */
	public boolean judgeSequeueIsAvailable(CnLongMessageQueue sequeue) {
		if(this.key.equals(sequeue.getKey()) && 
				CnLongMqRole.customer.name().equals(this.role) && 
				!this.id.equals(sequeue.getId()) && 
				CnLongMqStatus.active.name().equals(this.longMqStatus)
		) {
			return true;
		}
		return false;
	}
	
	/**
	 * 复制队列信息
	 */
	@Override
	public Object clone() throws CloneNotSupportedException {
		CnLongMessageQueue mqSeq = null;
		try {
			mqSeq = (CnLongMessageQueue) super.clone();
		} catch(Exception e) {
			e.printStackTrace();
		}
		return mqSeq;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public Integer getTimeout() {
		return timeout;
	}

	public void setTimeout(Integer timeout) {
		this.timeout = timeout;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getMode() {
		return mode;
	}

	public void setMode(String mode) {
		this.mode = mode;
	}

	public String getRole() {
		return role;
	}

	public void setRole(String role) {
		this.role = role;
	}

	public String getClassPath() {
		return classPath;
	}

	public void setClassPath(String classPath) {
		this.classPath = classPath;
	}

	public String getLongMqName() {
		return longMqName;
	}

	public void setLongMqName(String longMqName) {
		this.longMqName = longMqName;
	}

	public String getLongMqIp() {
		return longMqIp;
	}

	public void setLongMqIp(String longMqIp) {
		this.longMqIp = longMqIp;
	}

	public Integer getLongMqPort() {
		return longMqPort;
	}

	public void setLongMqPort(Integer longMqPort) {
		this.longMqPort = longMqPort;
	}

	public String getLongMqStatus() {
		return longMqStatus;
	}

	public void setLongMqStatus(String longMqStatus) {
		this.longMqStatus = longMqStatus;
	}

	public Date getStartActiveDate() {
		return startActiveDate;
	}

	public void setStartActiveDate(Date startActiveDate) {
		this.startActiveDate = startActiveDate;
	}

	public Date getStopDate() {
		return stopDate;
	}

	public void setStopDate(Date stopDate) {
		this.stopDate = stopDate;
	}

	public int getHeartbeatConnectNumber() {
		return heartbeatConnectNumber;
	}

	public void setHeartbeatConnectNumber(int heartbeatConnectNumber) {
		this.heartbeatConnectNumber = heartbeatConnectNumber;
	}

	public Date getHeartBeatData() {
		return heartBeatData;
	}

	public void setHeartBeatData(Date heartBeatData) {
		this.heartBeatData = heartBeatData;
	}

}
